package cn.iocoder.yudao.module.erp.service.bomgroupstandard;

import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import cn.iocoder.yudao.module.erp.controller.admin.bomgroupstandard.vo.*;
import cn.iocoder.yudao.module.erp.dal.dataobject.bomgroupstandard.BomGroupStandardDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.erp.dal.mysql.bomgroupstandard.BomGroupStandardMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;

/**
 * bom分组 Service 实现类
 *
 * @author lekailehuai
 */
@Service
@Validated
public class BomGroupStandardServiceImpl implements BomGroupStandardService {

    @Resource
    private BomGroupStandardMapper bomGroupStandardMapper;

    @Override
    public Long createBomGroupStandard(BomGroupStandardSaveReqVO createReqVO) {
        // 校验父节点的有效性
        validateParentBomGroupStandard(null, createReqVO.getParentid());
        // 校验名称的唯一性
        validateBomGroupStandardNameUnique(null, createReqVO.getParentid(), createReqVO.getName());

        // 插入
        BomGroupStandardDO bomGroupStandard = BeanUtils.toBean(createReqVO, BomGroupStandardDO.class);
        bomGroupStandardMapper.insert(bomGroupStandard);
        // 返回
        return bomGroupStandard.getId();
    }

    @Override
    public void updateBomGroupStandard(BomGroupStandardSaveReqVO updateReqVO) {
        // 校验存在
        validateBomGroupStandardExists(updateReqVO.getId());
        // 校验父节点的有效性
        validateParentBomGroupStandard(updateReqVO.getId(), updateReqVO.getParentid());
        // 校验名称的唯一性
        validateBomGroupStandardNameUnique(updateReqVO.getId(), updateReqVO.getParentid(), updateReqVO.getName());

        // 更新
        BomGroupStandardDO updateObj = BeanUtils.toBean(updateReqVO, BomGroupStandardDO.class);
        bomGroupStandardMapper.updateById(updateObj);
    }

    @Override
    public void deleteBomGroupStandard(Long id) {
        // 校验存在
        validateBomGroupStandardExists(id);
        // 校验是否有子bom分组
        if (bomGroupStandardMapper.selectCountByParentid(id) > 0) {
            throw exception(BOM_GROUP_STANDARD_EXITS_CHILDREN);
        }
        // 删除
        bomGroupStandardMapper.deleteById(id);
    }

    private void validateBomGroupStandardExists(Long id) {
        if (bomGroupStandardMapper.selectById(id) == null) {
            throw exception(BOM_GROUP_STANDARD_NOT_EXISTS);
        }
    }

    private void validateParentBomGroupStandard(Long id, Long parentid) {
        if (parentid == null || BomGroupStandardDO.PARENTID_ROOT.equals(parentid)) {
            return;
        }
        // 1. 不能设置自己为父bom分组
        if (Objects.equals(id, parentid)) {
            throw exception(BOM_GROUP_STANDARD_PARENT_ERROR);
        }
        // 2. 父bom分组不存在
        BomGroupStandardDO parentBomGroupStandard = bomGroupStandardMapper.selectById(parentid);
        if (parentBomGroupStandard == null) {
            throw exception(BOM_GROUP_STANDARD_PARENT_NOT_EXITS);
        }
        // 3. 递归校验父bom分组，如果父bom分组是自己的子bom分组，则报错，避免形成环路
        if (id == null) { // id 为空，说明新增，不需要考虑环路
            return;
        }
        for (int i = 0; i < Short.MAX_VALUE; i++) {
            // 3.1 校验环路
            parentid = parentBomGroupStandard.getParentid();
            if (Objects.equals(id, parentid)) {
                throw exception(BOM_GROUP_STANDARD_PARENT_IS_CHILD);
            }
            // 3.2 继续递归下一级父bom分组
            if (parentid == null || BomGroupStandardDO.PARENTID_ROOT.equals(parentid)) {
                break;
            }
            parentBomGroupStandard = bomGroupStandardMapper.selectById(parentid);
            if (parentBomGroupStandard == null) {
                break;
            }
        }
    }

    private void validateBomGroupStandardNameUnique(Long id, Long parentid, String name) {
        BomGroupStandardDO bomGroupStandard = bomGroupStandardMapper.selectByParentidAndName(parentid, name);
        if (bomGroupStandard == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的bom分组
        if (id == null) {
            throw exception(BOM_GROUP_STANDARD_NAME_DUPLICATE);
        }
        if (!Objects.equals(bomGroupStandard.getId(), id)) {
            throw exception(BOM_GROUP_STANDARD_NAME_DUPLICATE);
        }
    }

    @Override
    public BomGroupStandardDO getBomGroupStandard(Long id) {
        return bomGroupStandardMapper.selectById(id);
    }

    @Override
    public List<BomGroupStandardDO> getBomGroupStandardList(BomGroupStandardListReqVO listReqVO) {
        return bomGroupStandardMapper.selectList(listReqVO);
    }

    @Override
    public List<BomGroupStandardDO> getBomGroupStandardListByIds(Collection<Long> ids){
        return bomGroupStandardMapper.selectBatchIds(ids);
    }

}